export type Getter = <Value>(atom: ReadableAtom<Value>) => Value;

export type Setter = <Value, Args extends unknown[], Result>(
  atom: WritableAtom<Value, Args, Result>,
  ...args: Args
) => Result;

type Read<Value> = (get: Getter) => Value;

type Write<Args extends unknown[], Result> = (
  get: Getter,
  set: Setter,
  ...args: Args
) => Result;

export type ReadableAtom<Value> = {
  debugLabel: string;
  read: Read<Value>;
};

// Read-Write atom（可读可写原子）
export type WritableAtom<Value, Args extends unknown[], Result> = {
  write: Write<Args, Result>;
} & ReadableAtom<Value>;

type SetStateAction<Value> = Value | ((prev: Value) => Value);

// Primitive atom（原始原子）
export type PrimitiveAtom<Value> = WritableAtom<Value, [SetStateAction<Value>], void>;

export function atom<Value, Args extends unknown[], Result>(
  read: Value | Read<Value>,
  write?: Write<Args, Result>
) {
  // 交叉类型 可读可写原子） 交叉 {init?: Value}
  const config = {} as WritableAtom<Value, Args, Result> & { init?: Value };
  if (typeof read === 'function') {
    config.read = read as Read<Value>;
  } else {
    config.init = read;
    config.read = (get) => get(config);
    config.write = ((get: Getter, set: Setter, arg: SetStateAction<Value>) =>
      set(
        config as unknown as PrimitiveAtom<Value>,
        typeof arg === 'function' ? (arg as (prev: Value) => Value)(get(config)) : arg
      )) as unknown as Write<Args, Result>;
  }
  if (write) {
    config.write = write;
  }
  return config;
}

// 示例
// const priceAtom = atom(10);
// const readOnlyAtom = atom((get) => get(priceAtom) * 2);

// const writeOnlyAtom = atom(
//   null, // 为第一个参数传递 `null` 是一种惯例
//   (get, set, update) => {
//     // `update` 是我们收到的用于更新此原子的任何单个值
//     set(priceAtom, get(priceAtom) - update.discount);
//   }
// );
// const readWriteAtom = atom(
//   (get) => get(priceAtom) * 2,
//   (get, set, newPrice) => {
//     set(priceAtom, newPrice / 2);
//     // 您可以同时设置任意数量的原子
//   }
// );
